﻿using System;
using System.Text.RegularExpressions;
using BusinessBingo.CommandHandlers.Base;
using BusinessBingo.CommandHandlers.Interfaces;
using BusinessBingo.CommandHandlers.Results;
using BusinessBingo.Commands;
using BusinessBingo.Data.Interfaces;
using BusinessBingo.Model;
using BusinessBingo.Model.Interfaces;

namespace BusinessBingo.CommandHandlers
{
    public class GenerateUrlCommandHandler :
        BaseCommandHandler,
        IGenerateUrlCommandHandler
    {
        private ICheckForUrlUniquenessCommandHandler _checkForUrlUniquenessCommandHandler;

        public GenerateUrlCommandHandler(
            ICheckForUrlUniquenessCommandHandler checkForUrlUniquenessCommandHandler,
            IValidationState validationState,
            IUnitOfWork unitOfWork)
            : base(validationState, unitOfWork)
        {
            this._checkForUrlUniquenessCommandHandler = checkForUrlUniquenessCommandHandler;
        }

        public GenerateUrlCommandHandlerResult Execute(GenerateUrlCommand generateUrlCommand)
        {
            GenerateUrlCommandHandlerResult result = new GenerateUrlCommandHandlerResult();

            if (generateUrlCommand == default(GenerateUrlCommand))
                throw new ArgumentNullException("GenerateUrlCommand");

            if (string.IsNullOrWhiteSpace(generateUrlCommand.GroupName) == true)
                this._validationState.AddError<GenerateUrlCommand>(x => x.GroupName, ErrorTypes.Empty);

            if (this._validationState.IsValid == false) return result;

            string baseUrl = this.GenerateUrlPart(generateUrlCommand.GroupName);
            
            CheckForUrlUniquenessCommand checkForUrlUniquenessCommand = new CheckForUrlUniquenessCommand(baseUrl);

            CheckForUrlUniquenessCommandHandlerResult checkForUrlUniquenessCommandResult =
                this._checkForUrlUniquenessCommandHandler.Execute(checkForUrlUniquenessCommand);

            string returnUrl = baseUrl;
            int counter = 0;
            while(checkForUrlUniquenessCommandResult.IsUnique == false)
            {
                counter++;
                returnUrl = string.Format("{0}-{1}", baseUrl, counter);
                checkForUrlUniquenessCommand = new CheckForUrlUniquenessCommand(returnUrl);
                checkForUrlUniquenessCommandResult =
                    this._checkForUrlUniquenessCommandHandler.Execute(checkForUrlUniquenessCommand);
            }

            result.Succeeded = true;
            result.Url = returnUrl;

            return result;
        }

        private string GenerateUrlPart(string part)
        {
            Regex regex = new Regex("[^0-9a-zA-Z]*");
            return regex.Replace(part, string.Empty);
        }
    }
}